package com.dream.technology.mybatisUtils;


import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

/**
 * 描述：
 *
 * @author chen_q_i@163.com
 * 2018/12/12 : 13:38.
 * @version : 1.0
 */

@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class UpdateTimeInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        // 获取 SQL 命令
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        // 获取参数
        Object parameter = invocation.getArgs()[1];
        if (parameter != null) {
            if (parameter instanceof Map&&SqlCommandType.INSERT.equals(sqlCommandType) ){
                ArrayList<Object> list = (ArrayList<Object>) ((Map) parameter).get("list");
                for (int i = 0; i < list.size(); i++) {
                    Object o = list.get(i);
                    Field[] declaredFields = o.getClass().getDeclaredFields();
                    setDate(sqlCommandType, o, declaredFields);
                }
            }else {
                // 获取成员变量
                Field[] declaredFields = parameter.getClass().getDeclaredFields();
                setDate(sqlCommandType, parameter, declaredFields);
            }
        }
        //同样的方式也可以在这里添加create_time或者是id的生成等处理
        return invocation.proceed();
    }

    public void setDate(SqlCommandType sqlCommandType, Object parameter, Field[] declaredFields) throws IllegalAccessException {
        for (Field field : declaredFields) {
            if (field.getAnnotation(UpdateTime.class) != null) {
                // update 语句插入 updateTime
//                    if ( SqlCommandType.UPDATE.equals(sqlCommandType)|| SqlCommandType.INSERT.equals(sqlCommandType)) {
                    field.setAccessible(true);
//                        if (field.get(parameter) == null) {
                        field.set(parameter, new Date());
//                        }
//                    }
            }
            if (field.getAnnotation(CreateTime.class) != null) {
                //  insert 语句插入 CreateTime
                if ( SqlCommandType.INSERT.equals(sqlCommandType)) {
                    field.setAccessible(true);
                    if (field.get(parameter) == null) {
                    field.set(parameter, new Date());
                    }
                }
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}
